#include <iostream>
#include <string>
#include <sstream>
#include <sys/types.h> 

#include <QThread>
#include <PopupSetupDialog.hpp>
#include <PopupUtilities.hpp>
#include <PopupProgressWidget.hpp>
#include <PopupNotificationFrame.hpp>
#include <PopupGuiCore.hpp>

using namespace std;
using namespace utilities;
using namespace Popup;
using namespace PopupUtils;

const QString c_customFontColorBtnFormatStyle =
    "background-color:%1;border-radius:10px;height:20px;";
const QString c_customFontTestArea =
    "color:%1;font-family:%2;font-size:%3px;%4%5";

//==============================================================================
// Construction/Destruction
//==============================================================================

PopupSetupDialog::PopupSetupDialog(QWidget *parent)
: QDialog(parent),
  m_settings(PopupSettings::instance()),
  m_lastPosition(0,0)
{
  setupUi(this);
  initSettingsTab();
}

//==============================================================================
// Show/Close overrides
//==============================================================================

void PopupSetupDialog::hideEvent(QHideEvent*)
{
  m_lastPosition = pos();
}
//----------------------------------------------------------

void PopupSetupDialog::showEvent(QShowEvent*)
{
  if (m_lastPosition != QPoint(0,0))
  {
    move(m_lastPosition);
  }
}

//==============================================================================
// Initializations
//==============================================================================

void PopupSetupDialog::initSettingsTab()
{
  m_tempDirEdit->setText(m_settings->temporaryDirectory());
  m_resourceDirEdit->setText(m_settings->resourceDirectory());
  m_browserEdit->setText(m_settings->browser());
  m_videoPlayerEdit->setText(m_settings->videoPlayer());
  m_imageViewerEdit->setText(m_settings->imageViewer());
  m_lclickCombo->setCurrentIndex(m_settings->systrayAction(QSystemTrayIcon::Trigger));
  m_rclickCombo->setCurrentIndex(m_settings->systrayAction(QSystemTrayIcon::Context));
  m_mclickCombo->setCurrentIndex(m_settings->systrayAction(QSystemTrayIcon::MiddleClick));
  m_ldclickCombo->setCurrentIndex(m_settings->systrayAction(QSystemTrayIcon::DoubleClick));
  (m_settings->useEmbeddedImageViewer()?
      m_useEmbeddedViewerGroup->setChecked(Qt::Checked) :
      m_useEmbeddedViewerGroup->setChecked(Qt::Unchecked));
  (m_settings->isImageViewerOpacityFxEnabled()?
        m_enableOpacityFX->setChecked(Qt::Checked) :
        m_enableOpacityFX->setChecked(Qt::Unchecked));
  (m_settings->isImageViewerZoomFxEnabled()?
        m_enableZoomFX->setChecked(Qt::Checked) :
        m_enableZoomFX->setChecked(Qt::Unchecked));
  (m_settings->isImageViewerTransitionFxEnabled()?
      m_enableSlideFX->setChecked(Qt::Checked) :
      m_enableSlideFX->setChecked(Qt::Unchecked));
  QString _hpos, _vpos, _hEffect, _vEffect;
  m_settings->getImageViewerPosition(_hpos, _vpos);
  m_settings->getImageViewerTransition(_hEffect, _vEffect);
  m_imageHorizontalPosition->setCurrentIndex(
      m_imageHorizontalPosition->findText(_hpos));
  m_imageVerticalPosition->setCurrentIndex(
      m_imageVerticalPosition->findText(_vpos));
  m_imageHorizontalTransition->setCurrentIndex(
      m_imageHorizontalTransition->findText(_hEffect));
  m_imageVerticalTransition->setCurrentIndex(
      m_imageVerticalTransition->findText(_vEffect));
  (m_settings->automaticImageViewerShow()?
      m_automaticImageViewerShow->setChecked(Qt::Checked) :
      m_automaticImageViewerShow->setChecked(Qt::Unchecked));
  (m_settings->useFakePrompt()?
      m_useFakePromptChkbx->setChecked(Qt::Checked) :
      m_useFakePromptChkbx->setChecked(Qt::Unchecked));
  (m_settings->isFuckNotificationEnabled()?
      m_enableFuckNotifCheckBox->setChecked(Qt::Checked) :
      m_enableFuckNotifCheckBox->setChecked(Qt::Unchecked));
  (m_settings->isSuckNotificationEnabled()?
      m_enableSuckNotifCheckBox->setChecked(Qt::Checked) :
      m_enableSuckNotifCheckBox->setChecked(Qt::Unchecked));
  (m_settings->isLikeNotificationEnabled()?
      m_enableLikeNotifCheckBox->setChecked(Qt::Checked) :
      m_enableLikeNotifCheckBox->setChecked(Qt::Unchecked));
  (m_settings->isPoetryNotificationEnabled()?
      m_enablePoetryNotifCheckBox->setChecked(Qt::Checked) :
      m_enablePoetryNotifCheckBox->setChecked(Qt::Unchecked));
  (m_settings->isTransfersDialogBoxEnabled()?
      m_displayTransfersCheckBox->setChecked(Qt::Checked) :
      m_displayTransfersCheckBox->setChecked(Qt::Unchecked));

  (m_settings->framelessMessageDialog()?
      m_framelessMsgDlgCheckbox->setChecked(Qt::Checked) :
      m_framelessMsgDlgCheckbox->setChecked(Qt::Unchecked));
  (m_settings->updateEnabled()?
      m_enableUpdateManagerCheckbox->setChecked(Qt::Checked) :
      m_enableUpdateManagerCheckbox->setChecked(Qt::Unchecked));
  (m_settings->updateProxyEnabled()?
      m_enableUpdateProxyCheckbox->setChecked(Qt::Checked) :
      m_enableUpdateProxyCheckbox->setChecked(Qt::Unchecked));
  m_updateUrlEdit->setText(m_settings->updateUrl());
  m_updateProxyEdit->setText(m_settings->updateProxy());
  m_updateCheckDelaySpinbox->setValue(m_settings->updateCheckDelay());
  m_messageDialogStyleEdit->setPlainText(m_settings->messageDialogStyleSheet());

  (m_settings->customFontEnabled()?
        m_enableCustomFont->setChecked(Qt::Checked) :
        m_enableCustomFont->setChecked(Qt::Unchecked));
  //m_customFontComboBox->setEditText(m_settings->customFontName());
  m_customFontComboBox->setCurrentFont(QFont(m_settings->customFontName()));
  m_customFontSizeSpinBox->setValue(m_settings->customFontSize());
  m_customFontColorBtn->setStyleSheet(QString(c_customFontColorBtnFormatStyle).
                                      arg(m_settings->customFontColor()));
  (m_settings->customFontIsBold()?
      m_customFontBoldCheckBox->setChecked(Qt::Checked) :
      m_customFontBoldCheckBox->setChecked(Qt::Unchecked));
  (m_settings->customFontIsItalic()?
      m_customFontItalicCheckBox->setChecked(Qt::Checked) :
      m_customFontItalicCheckBox->setChecked(Qt::Unchecked));

  slot_updateCustomFontTestArea();

  // Add custom buttons
  const_collection_foreach(PopupSettings::instance()->customButtons(),
                           PopupCustomButtonList, _it) {
    m_buttonsList->addItem((*_it)->name());
  }
  enablecustomButtonsControls(CBTN_STATE_INIT);


  connect(m_browseBrowserBtn, SIGNAL(clicked()),
          this, SLOT(slot_browseFile()));
  connect(m_browseVideoPlayerBtn, SIGNAL(clicked()),
          this, SLOT(slot_browseFile()));
  connect(m_browseImageViewerBtn, SIGNAL(clicked()),
          this, SLOT(slot_browseFile()));
  connect(m_browseTempDirBtn, SIGNAL(clicked()),
          this, SLOT(slot_browseFile()));
  connect(m_browseResourceDirBtn, SIGNAL(clicked()),
          this, SLOT(slot_browseFile()));
  connect(m_applySettingsBtn, SIGNAL(clicked()),
          this, SLOT(slot_applySettings()));
  connect(m_revertMessageDialogStyleBtn, SIGNAL(clicked()),
          this, SLOT(slot_setDefaultStyleSheets()));
  connect(m_customFontComboBox, SIGNAL(currentFontChanged(QFont)),
          this, SLOT(slot_updateCustomFontTestArea()));
  connect(m_customFontSizeSpinBox, SIGNAL(valueChanged(int)),
          this, SLOT(slot_updateCustomFontTestArea()));
  connect(m_customFontBoldCheckBox, SIGNAL(toggled(bool)),
          this, SLOT(slot_updateCustomFontTestArea()));
  connect(m_customFontItalicCheckBox, SIGNAL(toggled(bool)),
          this, SLOT(slot_updateCustomFontTestArea()));
  connect(m_customFontColorBtn, SIGNAL(clicked()),
          this, SLOT(slot_browseCustomFontColor()));
  connect(m_customButtonSaveButton, SIGNAL(clicked()),
          this, SLOT(slot_saveCustomButton()));
  connect(m_customButtonCancelButton, SIGNAL(clicked()),
          this, SLOT(slot_cancelEditionOfCustomButton()));
  connect(m_setCustomButtonIconBtn, SIGNAL(clicked()),
          this, SLOT(slot_browseFile()));
  connect(m_setCustomButtonMediaBtn, SIGNAL(clicked()),
          this, SLOT(slot_browseFile()));
  connect(m_customButtonEditBtn, SIGNAL(clicked()),
            this, SLOT(slot_editCurrentlySelectedCustomButton()));
  connect(m_customButtonDeleteBtn, SIGNAL(clicked()),
          this, SLOT(slot_deleteCurrentlySelectedCustomButton()));
  connect(m_customButtonNameEdit, SIGNAL(textEdited (const QString &)),
          this, SLOT(slot_customButtonNameChanged(const QString &)));
}

//==============================================================================
// Settings management
//==============================================================================

void PopupSetupDialog::slot_applySettings()
{
  // Make sure temp dir exits
  if (!createDirectory(m_tempDirEdit->displayText().toStdString())) {
    showError("Failed to create temporary directory:\n" +
              m_tempDirEdit->displayText());
  } else {
    m_settings->setTemporaryDirectory(m_tempDirEdit->displayText());
  }
  if (!createDirectory(m_resourceDirEdit->displayText().toStdString())) {
    showError("Failed to create resources directory:\n" +
              m_resourceDirEdit->displayText());
  } else {
    m_settings->setResourceDirectory(m_resourceDirEdit->displayText());
  }

  m_settings->setBrowserPath(m_browserEdit->displayText());
  m_settings->setVideoPlayerPath(m_videoPlayerEdit->displayText());
  m_settings->setImageViewerPath(m_imageViewerEdit->displayText());
  m_settings->setUseEmbeddedImageViewer(m_useEmbeddedViewerGroup->isChecked());
  m_settings->setAutomaticImageViewerShow(m_automaticImageViewerShow->isChecked());
  m_settings->setEnableImageViewerTransitionFx(m_enableSlideFX->isChecked());
  m_settings->setEnableImageViewerOpacityFx(m_enableOpacityFX->isChecked());
  m_settings->setEnableImageViewerZoomFx(m_enableZoomFX->isChecked());
  m_settings->setImageViewerPosition(m_imageHorizontalPosition->currentText(),
                                     m_imageVerticalPosition->currentText());
  m_settings->setImageViewerTransitionFx(m_imageHorizontalTransition->currentText(),
                                         m_imageVerticalTransition->currentText());
  m_settings->setMessageDialogStyleSheet(m_messageDialogStyleEdit->toPlainText());
  m_settings->setFramelessMessageDialog(m_framelessMsgDlgCheckbox->isChecked());
  m_settings->setUseFakePrompt(m_useFakePromptChkbx->isChecked());
  m_settings->setFuckNotificationEnabled(m_enableFuckNotifCheckBox->isChecked());
  m_settings->setSuckNotificationEnabled(m_enableSuckNotifCheckBox->isChecked());
  m_settings->setLikeNotificationEnabled(m_enableLikeNotifCheckBox->isChecked());
  m_settings->setPoetryNotificationEnabled(m_enablePoetryNotifCheckBox->isChecked());
  m_settings->setTransfersDialogBoxEnabled(m_displayTransfersCheckBox->isChecked());
  m_settings->setUpdateEnabled(m_enableUpdateManagerCheckbox->isChecked());
  m_settings->setUpdateUrl(m_updateUrlEdit->displayText());
  m_settings->setUpdateProxyEnabled(m_enableUpdateProxyCheckbox->isChecked());
  m_settings->setUpdateProxy(m_updateProxyEdit->displayText());
  m_settings->setUpdateCheckDelay(m_updateCheckDelaySpinbox->value());
  m_settings->setSystrayAction(QSystemTrayIcon::Trigger,
                               (PopupSettings::PopupSystrayAction) m_lclickCombo->currentIndex());
  m_settings->setSystrayAction(QSystemTrayIcon::Context,
                               (PopupSettings::PopupSystrayAction) m_rclickCombo->currentIndex());
  m_settings->setSystrayAction(QSystemTrayIcon::MiddleClick,
                               (PopupSettings::PopupSystrayAction) m_mclickCombo->currentIndex());
  m_settings->setSystrayAction(QSystemTrayIcon::DoubleClick,
                               (PopupSettings::PopupSystrayAction) m_ldclickCombo->currentIndex());
  m_settings->setCustomFontEnabled(m_enableCustomFont->isChecked());
  m_settings->setCustomFontName(m_customFontComboBox->currentFont().family());
  m_settings->setCustomFontColor(getCustomFontCurrentColor());
  m_settings->setCustomFontSize(m_customFontSizeSpinBox->value());
  m_settings->setCustomFontIsBold(m_customFontBoldCheckBox->isChecked());
  m_settings->setCustomFontIsItalic(m_customFontItalicCheckBox->isChecked());
  m_settings->serialize(PopupSettings::POPUP_SAVE_TO_FILE);

  emit signal_applyNewSettings();
}
//----------------------------------------------------------

void PopupSetupDialog::slot_setDefaultStyleSheets()
{
  m_messageDialogStyleEdit->setPlainText(PopupSettings::MESSAGE_DIALOG_DEFAULT_STYLESHEET);
  slot_applySettings();
}
//----------------------------------------------------------

void PopupSetupDialog::slot_browseFile()
{
  QObject *_emitter = QObject::sender();

  if (_emitter == m_browseBrowserBtn)
  {
    selectFileToTextEdit(m_browserEdit, this,
                         tr("Selection of Popup default Internet browser"),
                         tr("Executable files (*)"));
  }
  else if (_emitter == m_browseVideoPlayerBtn)
  {
    selectFileToTextEdit(m_videoPlayerEdit, this,
                         tr("Selection of Popup default video player"),
                         tr("Executable files (*)"));
  }
  else if (_emitter == m_browseImageViewerBtn)
  {
    selectFileToTextEdit(m_imageViewerEdit, this,
                         tr("Selection of Popup default image viewer"),
                         tr("Executable files (*)"));
  }
  else if (_emitter == m_browseTempDirBtn)
  {
    selectDirToTextEdit(m_tempDirEdit, this,
                        tr("Selection of Popup temporary directory..."));
  }
  else if (_emitter == m_browseResourceDirBtn)
  {
    selectDirToTextEdit(m_resourceDirEdit, this,
                        tr("Selection of Popup resource directory..."));
  }
  else if (_emitter == m_setCustomButtonIconBtn)
  {
    selectFileToTextEdit(m_customButtonIconEdit, this,
                             tr("Select icon for your custom button"),
                             tr("Image files (*.png *.jpg *gif)"));
    m_setCustomButtonIconBtn->setIcon(QIcon(m_customButtonIconEdit->text()));

  }
  else if (_emitter == m_setCustomButtonMediaBtn)
  {
    selectFileToTextEdit(m_customButtonMediaEdit, this,
                             tr("Select media file to associate to your custom button"),
                             tr("All files (*)"));
  }
  else
  {
    error("%s: Unexpected signal emitter", __FUNCTION__);
  }
}
//----------------------------------------------------------

void PopupSetupDialog::slot_browseCustomFontColor()
{
  QColor _currentColor = getCustomFontCurrentColor();
  QColor _newColor = QColorDialog::getColor(
      _currentColor, this, "Please select font color");
  m_customFontColorBtn->setStyleSheet(
      QString(c_customFontColorBtnFormatStyle).arg(_newColor.name()));
  slot_updateCustomFontTestArea();
}
//----------------------------------------------------------

QString PopupSetupDialog::getCustomFontCurrentColor()
{
  // Ugly! I know!
  return m_customFontColorBtn->styleSheet().mid(17,7);
}
//----------------------------------------------------------

void PopupSetupDialog::slot_updateCustomFontTestArea()
{
  m_customFontTestAreaEdit->setStyleSheet(
      QString(c_customFontTestArea).arg(
          getCustomFontCurrentColor(),
          m_customFontComboBox->currentFont().family(),
          QString::number(m_customFontSizeSpinBox->value()),
          (m_customFontBoldCheckBox->isChecked()? "font-weight:bold;":""),
          (m_customFontItalicCheckBox->isChecked()? "font-style:italic;":"")));
}
//----------------------------------------------------------

void PopupSetupDialog::slot_saveCustomButton()
{
  if (m_customButtonNameEdit->text().length() == 0)
  {
    utilities::showError("Button ID cannot be empty!");
  }
  else
  {
    if (m_settings->addCustomButton(m_customButtonNameEdit->text(),
                                    m_customButtonIconEdit->text(),
                                    m_customButtonMediaEdit->text(),
                                    m_customButtonTextEdit->toPlainText()))
    {
      m_buttonsList->addItem(m_customButtonNameEdit->text());
    }
  }
  slot_cancelEditionOfCustomButton();
}
//----------------------------------------------------------

void PopupSetupDialog::slot_cancelEditionOfCustomButton()
{
  m_customButtonNameEdit->clear();
  m_customButtonIconEdit->clear();
  m_customButtonMediaEdit->clear();
  m_customButtonTextEdit->clear();
  m_setCustomButtonIconBtn->setIcon(QIcon());
  enablecustomButtonsControls(CBTN_STATE_INIT);
}
//----------------------------------------------------------

void PopupSetupDialog::slot_editCurrentlySelectedCustomButton()
{
  QString _btnName = m_buttonsList->item(m_buttonsList->currentRow())->text();
  PopupCustomButton *_btn = PopupSettings::instance()->customButton(_btnName);
  if (_btn != 0)
  {
    m_customButtonNameEdit->setText(_btnName);
    m_customButtonIconEdit->setText(_btn->iconPath());
    m_customButtonMediaEdit->setText(_btn->mediaUrl());
    m_customButtonTextEdit->setText(_btn->msgText());
    if (_btn->iconPath().length() > 0) {
      m_setCustomButtonIconBtn->setIcon(QIcon(_btn->iconPath()));
    }
  }
  enablecustomButtonsControls(CBTN_STATE_EDIT_BUTTON);
}
//----------------------------------------------------------

void PopupSetupDialog::slot_deleteCurrentlySelectedCustomButton()
{
  int _row = m_buttonsList->currentRow();
  PopupSettings::instance()->deleteCustomButton(m_buttonsList->item(_row)->text());
  delete m_buttonsList->takeItem(_row);
}
//----------------------------------------------------------

void PopupSetupDialog::enablecustomButtonsControls(CustomButtonState p_state)
{
  bool enableButtonNameControls = false;
  bool enableButtonPptyControls = false;
  bool enableButtonListControls = false;

  switch(p_state)
  {
    case CBTN_STATE_INIT:
      enableButtonNameControls = true;
      enableButtonListControls = true;
      break;
    case CBTN_STATE_NEW_BUTTON:
      enableButtonNameControls = true;
      enableButtonPptyControls = true;
      break;
    case CBTN_STATE_EDIT_BUTTON:
      enableButtonPptyControls = true;
      break;
  }

  // Button ID
  m_customButtonNameLabel->setEnabled(enableButtonNameControls);
  m_customButtonNameEdit->setEnabled(enableButtonNameControls);
  // Buttons properties
  m_setCustomButtonIconBtn->setEnabled(enableButtonPptyControls);
  m_customButtonIconEdit->setEnabled(enableButtonPptyControls);
  m_setCustomButtonMediaBtn->setEnabled(enableButtonPptyControls);
  m_customButtonMediaEdit->setEnabled(enableButtonPptyControls);
  m_customButtonTextLabel->setEnabled(enableButtonPptyControls);
  m_customButtonTextEdit->setEnabled(enableButtonPptyControls);
  m_customButtonSaveButton->setEnabled(enableButtonPptyControls);
  m_customButtonCancelButton->setEnabled(enableButtonPptyControls);
  // Buttons list
  m_buttonsList->setEnabled(enableButtonListControls);
  m_customButtonEditBtn->setEnabled(enableButtonListControls);
  m_customButtonDeleteBtn->setEnabled(enableButtonListControls);
}

void PopupSetupDialog::slot_customButtonNameChanged(const QString & p_name)
{
  if (PopupSettings::instance()->customButton(p_name) != 0) {
    m_customButtonNameErrorLabel->setText("This name is already used");
  } else {
    m_customButtonNameErrorLabel->clear();
  }

  if (p_name.length() > 0) {
    enablecustomButtonsControls(CBTN_STATE_NEW_BUTTON);
  } else {
    enablecustomButtonsControls(CBTN_STATE_INIT);
  }
}
